<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram - Normal Modes</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #fff;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="500" height="450"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // Parameters
        const cx = canvas.width / 2;
        const cy = 150;
        const R_val = 150;
        const massRadius = 6;
        const springAmplitude = 4;
        const numZigs = 16; 

        // Colors and styles
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 2;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';

        // Helper function to draw an arrowhead
        function drawArrowhead(fromX, fromY, toX, toY, headLength) {
            const angle = Math.atan2(toY - fromY, toX - fromX);
            ctx.beginPath();
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - headLength * Math.cos(angle - Math.PI / 6), toY - headLength * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - headLength * Math.cos(angle + Math.PI / 6), toY - headLength * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
        }

        // 1. Draw the circular path
        ctx.beginPath();
        const arcStartAngle = 0.1 * Math.PI;
        const arcEndAngle = 0.9 * Math.PI;
        ctx.arc(cx, cy, R_val, arcStartAngle, arcEndAngle);
        ctx.lineWidth = 2.5;
        ctx.stroke();
        ctx.lineWidth = 1.5; // Reset line width for other elements

        // 2. Draw the radius line 'R'
        const angleR = 0.3 * Math.PI;
        const xR_start = cx;
        const yR_start = cy;
        const xR_end = cx + R_val * Math.cos(angleR);
        const yR_end = cy + R_val * Math.sin(angleR);
        ctx.beginPath();
        ctx.moveTo(xR_start, yR_start);
        ctx.lineTo(xR_end, yR_end);
        ctx.stroke();
        drawArrowhead(xR_start, yR_start, xR_end, yR_end, 8);
        
        // Label 'R'
        ctx.font = "italic 22px serif";
        const xR_label = cx + (R_val * 0.6) * Math.cos(angleR);
        const yR_label = cy + (R_val * 0.6) * Math.sin(angleR) - 10;
        ctx.fillText('R', xR_label, yR_label);

        // 3. Draw the vertical dashed line
        ctx.beginPath();
        ctx.setLineDash([4, 4]);
        ctx.moveTo(cx, cy);
        ctx.lineTo(cx, cy + R_val);
        ctx.stroke();
        ctx.setLineDash([]); // Reset line dash

        // 4. Draw gravity vector 'g'
        const gx = cx + 55;
        const gy_start = cy + 50;
        const gy_end = cy + 100;
        ctx.beginPath();
        ctx.moveTo(gx, gy_start);
        ctx.lineTo(gx, gy_end);
        ctx.stroke();
        drawArrowhead(gx, gy_start, gx, gy_end, 8);
        
        // Label 'g'
        ctx.font = "italic 22px serif";
        ctx.fillText('g', gx + 18, (gy_start + gy_end) / 2);

        // 5. Define mass positions
        const d_theta_m = 0.45;
        const theta_M = Math.PI / 2;
        const theta_L = theta_M - d_theta_m;
        const theta_R = theta_M + d_theta_m;

        const pos_M = { x: cx + R_val * Math.cos(theta_M), y: cy + R_val * Math.sin(theta_M) };
        const pos_L = { x: cx + R_val * Math.cos(theta_L), y: cy + R_val * Math.sin(theta_L) };
        const pos_R = { x: cx + R_val * Math.cos(theta_R), y: cy + R_val * Math.sin(theta_R) };

        // 6. Draw springs
        // Function to draw zigzag on arc
        function drawZigzagArc(startAngle, endAngle) {
            const totalAngle = endAngle - startAngle;
            const angleStep = totalAngle / numZigs;
            ctx.beginPath();
            ctx.moveTo(
                cx + R_val * Math.cos(startAngle),
                cy + R_val * Math.sin(startAngle)
            );
            for (let i = 1; i < numZigs; i++) {
                const currentAngle = startAngle + i * angleStep;
                const r = R_val + springAmplitude * (i % 2 === 0 ? -1 : 1);
                ctx.lineTo(
                    cx + r * Math.cos(currentAngle),
                    cy + r * Math.sin(currentAngle)
                );
            }
            ctx.lineTo(
                cx + R_val * Math.cos(endAngle),
                cy + R_val * Math.sin(endAngle)
            );
            ctx.stroke();
        }

        // Draw left spring
        drawZigzagArc(theta_L, theta_M);
        // Draw right spring
        drawZigzagArc(theta_M, theta_R);

        // 7. Draw masses
        function drawMass(pos) {
            ctx.beginPath();
            ctx.arc(pos.x, pos.y, massRadius, 0, 2 * Math.PI);
            ctx.fill();
        }
        drawMass(pos_L);
        drawMass(pos_M);
        drawMass(pos_R);

        // 8. Draw mass labels
        ctx.font = "italic 22px serif";
        ctx.fillText('m', pos_L.x - 5, pos_L.y + 25);
        ctx.fillText('M', pos_M.x, pos_M.y + 25);
        ctx.fillText('m', pos_R.x + 5, pos_R.y + 25);
        
        // 9. Draw caption
        ctx.font = "20px serif";
        ctx.fillText('Fig. 2.65.', cx, canvas.height - 25);

    </script>
</body>
</html>